package service

import (
	"encoding/json"
	"fmt"
	"github.com/jinzhu/copier"
	"github.com/sirupsen/logrus"
	"gorm.io/gorm"
	"hcy-api/lib/id"
	"hcy-api/lib/jwt"
	"hcy-api/structs/base"
	"hcy-api/structs/enum"
	"hcy-api/structs/tables"
	"hcy-api/structs/vap"
	"time"
	"vap/daemon/tcp"
	"vap/global"
	"vap/module/dao"
)

var ClusterService = new(clusterService)

type clusterService struct {
}

func (s *clusterService) AddCluster(in vap.AddClusterDto, self *jwt.CustomClaims) (clusterId int64, err error) {
	m := new(tables.VapCluster)
	err = copier.Copy(m, in)
	if err != nil {
		return 0, err
	}
	m.Id = id.GetSnowId()
	m.CreatorId = self.UserID
	m.Creator = self.Nickname
	m.CreatedAt = time.Now().Unix()
	err = global.DB.Save(m).Error
	return m.Id, err
}

// IssueApp 目前只支持公开应用发布，关于应用的细节权限在java中实现。或者有项目能落地需要时实现
func (s *clusterService) IssueApp(in vap.IssueAppDto) (err error) {
	err = global.DB.Transaction(func(tx *gorm.DB) error {
		m := new(tables.VapAppIssue)
		err = copier.Copy(m, in)
		if err != nil {
			return err
		}
		m.Id = id.GetSnowId()
		return tx.Create(m).Error
	})
	return err
}

func (s *clusterService) AppList(nameStr string) (li []vap.AppDetail, err error) {
	var (
		appList []tables.VapAppIssue
	)
	err = global.DB.Model(&tables.VapAppIssue{}).Where("app_name like ? or alias like ?", fmt.Sprintf("%%%s%%", nameStr),
		fmt.Sprintf("%%%s%%", nameStr)).Find(&appList).Error
	if err != nil {
		return
	}
	li = make([]vap.AppDetail, len(appList))
	for i, v := range appList {
		var clu tables.VapCluster
		err = global.DB.Model(&tables.VapCluster{}).Where(&tables.VapCluster{Id: v.ClusterId}).Find(&clu).Error
		if err != nil {
			logrus.Error(err)
		} else {
			li[i] = vap.AppDetail{
				AppIssue: v,
				Cluster:  clu,
			}
		}
	}
	return
}

// GetHostListByClusterId 获取集群主机，包含本集群和未分配主机的集群,当 clusterId =0为查询为未绑定的主机
func (s *clusterService) GetHostListByClusterId(clusterIds []int64) (li []tables.VapHost, err error) {
	err = global.DB.Model(&tables.VapHost{}).Where("cluster_id in ?", clusterIds).Find(&li).Error
	return
}

// UpdateHostAppList 通知主机上报更新应用信息
func (s *clusterService) UpdateHostAppList(hostId int64, iconPath string) (err error) {
	plug := vap.PluginInstruct{
		Cmd:             enum.BasePlugin,
		Args:            []string{fmt.Sprintf("-apps=%s", iconPath)},
		TimeoutDuration: 10,
	}
	bs, err := json.Marshal(plug)
	if err != nil {
		return err
	}
	inst := base.ClientInstruct{
		Type: enum.CloudApps,
		Body: string(bs),
	}
	host, err := dao.HostRepository.FindHostById(hostId)
	if err != nil {
		return
	}
	err = tcp.TcpServer.SendInstruct(host.Uid, inst)
	return err
}
